﻿using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using Toenda.Tools.Drawing;
using Toenda.Rails.DataContainer;
using Toenda.Rails.System;

namespace ZapprService {
	/// <summary>
	/// Zusammenfassungsbeschreibung für ZapprService
	/// </summary>
	//[WebService(Namespace = "http://soap.zappr.net/")]
	[WebService(Namespace = "http://localhost:3076/ZapprService/")]
	[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
	[ToolboxItem(false)]
	public class ZapprService : System.Web.Services.WebService {
		/// <summary>
		/// Get the name of the service
		/// </summary>
		/// <returns></returns>
		[WebMethod]
		public string GetName() {
			return "ZapprService " + AssemblyVersion.ToString();
		}

		/// <summary>
		/// Upload a picture to zappr
		/// </summary>
		/// <param name="img"></param>
		/// <param name="name"></param>
		/// <param name="desc"></param>
		/// <param name="tags"></param>
		/// <returns></returns>
		[WebMethod]
		public bool UploadPicture(string username, byte[] password, byte[] img, string name, int privacy, string[] tags) {
			if(img == null)
				return false;

			DBClient db = new DBClient();
			if(db.Login(username, password) == ErrorType.NoError) {
				MemoryStream ms = new MemoryStream(img);

				if(ms.Length == 0) {
					return false;
				}
				else {
					bool canUpload = false;
					double u = 0.0;
					string path = DBInfo.Current.ServerPath;
					AccountProvider ap = new AccountProvider();
					ImageGenerator ig = new ImageGenerator();
					ImageProvider ip = new ImageProvider();

					Account acc = ap.GetAccountByUsername(username);

					// check if user can upload
					u = ap.GetUsersUploadedMB(acc.ID);

					if(u < Convert.ToDouble(acc.MaxStorageMB)) {
					    canUpload = true;
					}
					else {
					    canUpload = false;
					}

					if(acc.Type == 0 && canUpload) {
					    File.WriteAllBytes(
					        Server.MapPath("Temp") + "\\" + name + ".jpg",
					        img
					    );

					    FileInfo fi = new FileInfo(
					        Server.MapPath("Temp") + "\\" + name + ".jpg"
					    );

					    long len = (fi.Length / 1024) / 1024;

					    if(len > 5) {
					        canUpload = false;
					    }

					    fi.Delete();
					}

					if(canUpload) {
						string image_guid = Guid.NewGuid().ToString(); ;
					    string temp_filename = "";
					    string imgs_filename = "";

					    // temp upload
					    DirectoryInfo imgs = new DirectoryInfo(path + "Images/");
					    imgs_filename = imgs.FullName + image_guid + "_org.jpg";

					    DirectoryInfo temp = new DirectoryInfo(path + "Temp/");
					    temp_filename = temp.FullName + image_guid + "_org.jpg";

					    FileInfo tmpfile = new FileInfo(temp_filename);

					    File.WriteAllBytes(
					        temp_filename,
					        img
					    );

					    // generate images
					    Bitmap imageOrg = new Bitmap(temp_filename);
					    Bitmap image1024 = ig.Generate1024Pixel(imageOrg);
					    Bitmap image500 = ig.Generate500Pixel(imageOrg);
					    Bitmap image240 = ig.Generate240Pixel(imageOrg);
					    Bitmap image100 = ig.Generate100Pixel(imageOrg);
					    Bitmap image75 = ig.Generate75x75Pixel(imageOrg);

					    // save in database
					    ImageItem item1 = new ImageItem();
					    item1.ID = Guid.NewGuid().ToString();
					    item1.Access = privacy;
					    item1.Name = name;
						item1.Description = "";
						item1.UserID = acc.ID;
						item1.UploadDate = DateTime.Now;

						item1.ImageOriginal = image_guid + "_org.jpg";

						if(image1024 != null) {
							item1.Image1024 = image_guid + "_1024.jpg";
						}

						if(image500 != null) {
							item1.Image500 = image_guid + "_500.jpg";
						}

						if(image240 != null) {
							item1.Image240 = image_guid + "_240.jpg";
						}

						if(image100 != null) {
							item1.Image100 = image_guid + "_100.jpg";
						}

						if(image75 != null) {
							item1.Image75x75 = image_guid + "_75x75.jpg";
						}

						foreach(string t in tags) {
							TagItem tag = new TagItem();
							tag.ID = Guid.NewGuid().ToString();
							tag.Tag = t;

							item1.Tags.Add(tag);
						}

						// upload
						imageOrg.Save(imgs_filename, ImageFormat.Jpeg);

						imgs_filename = imgs_filename.Replace("_org.jpg", "");

						if(image1024 != null) {
							image1024.Save(imgs_filename + "_1024.jpg", ImageFormat.Jpeg);
							image1024.Dispose();
						}

						if(image500 != null) {
							image500.Save(imgs_filename + "_500.jpg", ImageFormat.Jpeg);
							image500.Dispose();
						}

						if(image240 != null) {
							image240.Save(imgs_filename + "_240.jpg", ImageFormat.Jpeg);
							image240.Dispose();
						}

						if(image100 != null) {
							image100.Save(imgs_filename + "_100.jpg", ImageFormat.Jpeg);
							image100.Dispose();
						}

						if(image75 != null) {
							image75.Save(imgs_filename + "_75x75.jpg", ImageFormat.Jpeg);
							image75.Dispose();
						}

						// count max upload mb
						double size = Convert.ToDouble(tmpfile.Length);
						size = size / 1024;
						size = size / 1024;

						size = Math.Round(size, 3);

						ap.CountUserUploadedMB(acc.ID, size);

						// dispose the original image
						// and save the image item
						// and finaly delete temp image
						imageOrg.Dispose();
						ip.SaveImage(item1);
						tmpfile.Delete();

						// re/generate badge
						BadgeSettings bs = ip.GetBadgeSetting(acc.ID);

						if(bs != null && bs.ID != "") {
							string code = ip.GenerateZapprBadge(
								bs,
								Server.MapPath("Badges/"),
								Server.MapPath("Images/")
							);
						}
					}

					// test
					//File.WriteAllBytes(
					//    Server.MapPath("Temp") + "\\" + name + ".jpg",
					//    img
					//);

					return true;
				}
			}
			else {
				return false;
			}
		}

		// -----------------------------------------
		// PROPERTIES
		// -----------------------------------------

		/// <summary>
		/// Get the Assembly version
		/// </summary>
		private string AssemblyVersion {
			get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
		}
	}
}
